# ~*~ coding: utf-8 ~*~
import os
import base64
import pyotp

from flask import current_app, request
from flask_login import current_user
from ..extensions import cache


def generate_otp_uri(issuer="bees"):
    otp_secret_key = cache.get('{}_{}'.format('otp_key', current_user.id))
    if not otp_secret_key:
        otp_secret_key = base64.b32encode(os.urandom(10)).decode('utf-8')
    cache.set('{}_{}'.format('otp_key', current_user.id), otp_secret_key, 600)

    totp = pyotp.TOTP(otp_secret_key)
    otp_issuer_name = current_app.config.get('OTP_ISSUER_NAME') or issuer
    return totp.provisioning_uri(name=current_user.username, issuer_name=otp_issuer_name), otp_secret_key


def check_otp_code(otp_secret_key, otp_code):
    if not otp_secret_key or not otp_code:
        return False
    totp = pyotp.TOTP(otp_secret_key)
    otp_valid_window = current_app.config.get('OTP_VALID_WINDOW') or 0
    return totp.verify(otp=otp_code, valid_window=otp_valid_window)

# def get_password_check_rules():
#     check_rules = []
#     for rule in current_app.config.get('SECURITY_PASSWORD_RULES'):
#         key = "id_{}".format(rule.lower())
#         value = getattr(settings, rule)
#         if not value:
#             continue
#         check_rules.append({'key': key, 'value': int(value)})
#     return check_rules
#
#
# def check_password_rules(password):
#     pattern = r"^"
#     if settings.SECURITY_PASSWORD_UPPER_CASE:
#         pattern += '(?=.*[A-Z])'
#     if settings.SECURITY_PASSWORD_LOWER_CASE:
#         pattern += '(?=.*[a-z])'
#     if settings.SECURITY_PASSWORD_NUMBER:
#         pattern += '(?=.*\d)'
#     if settings.SECURITY_PASSWORD_SPECIAL_CHAR:
#         pattern += '(?=.*[`~!@#\$%\^&\*\(\)-=_\+\[\]\{\}\|;:\'\",\.<>\/\?])'
#     pattern += '[a-zA-Z\d`~!@#\$%\^&\*\(\)-=_\+\[\]\{\}\|;:\'\",\.<>\/\?]'
#     pattern += '.{' + str(settings.SECURITY_PASSWORD_MIN_LENGTH-1) + ',}$'
#     match_obj = re.match(pattern, password)
#     return bool(match_obj)

# SECURITY_PASSWORD_MIN_LENGTH = 6  # Unit: bit
# SECURITY_PASSWORD_UPPER_CASE = False
# SECURITY_PASSWORD_LOWER_CASE = False
# SECURITY_PASSWORD_NUMBER = False
# SECURITY_PASSWORD_SPECIAL_CHAR = False
#
# SECURITY_PASSWORD_RULES = [
#     'SECURITY_PASSWORD_MIN_LENGTH',
#     'SECURITY_PASSWORD_UPPER_CASE',
#     'SECURITY_PASSWORD_LOWER_CASE',
#     'SECURITY_PASSWORD_NUMBER',
#     'SECURITY_PASSWORD_SPECIAL_CHAR'
# ]
